local extension = Package("heroes_ev1")
extension.extensionName = "evolution"
--extension.game_modes_whitelist = {"brokenroyal_mode"}

local EV = require "packages/evolution/EV"
local U = require "packages/utility/utility"

Fk:loadTranslationTable{
  ["heroes_ev1"] = "新约角色01-04",
  ["ev"] = "新约",
  ["ev_sp"] = "新约SP",
  ["#AddTargetsBySkill"] = "用于 %arg 的效果，%from 使用的 %arg2 增加了目标 %to",
}

Achilles = General(extension, "ev__achilles", "ev", 4)

local ev__jifengnutao = fk.CreateActiveSkill{
  name = "ev__jifengnutao",
  anim_type = "support",
  prompt = "你可以弃置任意张黑色牌",
  card_num = function(self)
    return Self:usedSkillTimes(self.name) + 1
  end,
  target_num = 0,
  can_use = function(self, player)
    return not player:isNude()
  end,
  card_filter = function(self, to_select, selected)
    return Fk:getCardById(to_select).color == Card.Black
  end,
  target_filter = Util.FalseFunc,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    room:addPlayerMark(player, "@jifengnutao-turn", #effect.cards)
    room:moveCardTo(effect.cards, Card.DiscardPile, nil, fk.ReasonDiscard, self.name, "", true, player.id)
    room:setPlayerMark(player, "BypassTimesLimit", 1)
    U.askForUseVirtualCard(room, player, "ev__slash", nil, self.name)
    room:setPlayerMark(player, "BypassTimesLimit", 0)
  end,
}

local jifengnutao_trigger = fk.CreateTriggerSkill{
  name = "#jifengnutao_trigger",
  mute = true,
  anim_type = "offensive",
  events = {fk.TargetSpecifying},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) and data.card.trueName == "slash"
    and data.card.skillName == "ev__jifengnutao" and data.tos and #AimGroup:getAllTargets(data.tos) == 1 then
      local targets = U.getUseExtraTargets(player.room, data, false, true)
      targets = table.filter(targets, function(p) return player.room:getPlayerById(p):getMark("jifengnutao-turn") > 0 end)
      return #targets > 0
    end
  end,
  on_cost = function(self, event, target, player, data)
    local targets = U.getUseExtraTargets(player.room, data, false, true)
    targets = table.filter(targets, function(p) return player.room:getPlayerById(p):getMark("jifengnutao-turn") > 0 end)
    local tos = player.room:askForChoosePlayers(player, targets, 1, 999, "#jifengnutao-choose", self.name, true)
    if #tos > 0 then
      self.cost_data = tos
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    for _, pid in ipairs(self.cost_data) do
      AimGroup:addTargets(room, data, pid)
    end
    room:sendLog{
      type = "#AddTargetsBySkill",
      from = player.id,
      to = self.cost_data,
      arg = self.name,
      arg2 = data.card:toLogString()
    }
  end,

  refresh_events = {fk.TargetConfirmed},
  can_refresh = function(self, event, target, player, data)
    return target ~= player and player:hasSkill(self) and data.card.trueName == "slash"
  end,
  on_refresh = function(self, event, target, player, data)
    player.room:addPlayerMark(target, "jifengnutao-turn")
  end
}

local jifengnutao_distance = fk.CreateDistanceSkill{
  name = "#jifengnutao_distance",
  frequency = Skill.Compulsory,
  correct_func = function(self, from)
    if from:hasSkill(self) and from:getMark("@jifengnutao-turn") > 0 then
      return 0 - from:getMark("@jifengnutao-turn")
    end
  end,
}

local ev__budiao = fk.CreateTriggerSkill{
  name = "ev__budiao",
  anim_type = "defensive",
  frequency = Skill.Compulsory,
  events = {fk.DamageInflicted},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self.name)
    and table.find(player:getCardIds(Player.Hand), function(id) return Fk:getCardById(id):getMark("@@shown-inhand") == 0 end)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local card = -1
    if data.from then
      card = EV.askForCardChosen(player.room, data.from, player, "hs", self.name)
    else
      card = player.room:askForCard(player, 1, 1, false, self.name, false, ".", "#ev__budiao-show")
      if #card > 0 then
        card = card[1]
      end
    end
    if card < 0 then card = player:getCardIds(Player.Hand)[1] end
    player:showCards({card})
    if table.every(player:getCardIds(Player.Hand), function(id) return Fk:getCardById(id).number >= Fk:getCardById(card).number end) then
      room:loseHp(player, 1, self.name)
    else
      return true
    end
  end,
}

ev__jifengnutao:addRelatedSkill(jifengnutao_trigger)
ev__jifengnutao:addRelatedSkill(jifengnutao_distance)
Achilles:addSkill(ev__jifengnutao)
Achilles:addSkill(ev__budiao)

Fk:loadTranslationTable{
    ["ev__achilles"] = "阿喀琉斯",
    ["designer:ev__achilles"] = "KINGDOM43",
    ["ev__jifengnutao"] = "疾风怒涛",
    ["@jifengnutao-turn"] = "疾风怒涛",
    ["#jifengnutao-choose"] = "你可以为%arg额外增加任意个目标",
    [":ev__jifengnutao"] = "出牌阶段，你可弃置X张黑色牌，令你于本回合内与其他角色的距离-X；然后你视为使用【杀】，此【杀】可额外选择于本回合内成为过【杀】的目标的角色为目标（X为你于本回合内发动过此技能的次数+1）。",
    ["ev__budiao"] = "不凋之花",
    [":ev__budiao"] = "锁定技，当你受到伤害时，若此伤害有/无来源，伤害来源/你选择你的一张手牌，展示之：若此牌为你点数最小的手牌，你失去1点体力；否则你防止此伤害。",
    ["#ev__budiao-show"] = "不凋之花：请展示一张手牌",
  }

local Patchouli = General(extension, "ev__patchouli", "ev", 3, 3, General.Female)
local ev__qiyao = fk.CreateViewAsSkill{
  name = "ev__qiyao",
  pattern = ".|.|.|.|.|trick|.",
  prompt = "#ev__qiyao",
  interaction = function()
    local all_names = U.getAllCardNames("t")
    local names = U.getViewAsCardNames(Self, "ev__qiyao", all_names, {}, U.getMark(Self, "ev__qiyao-turn"))
    if #names == 0 then return false end
    return U.CardNameBox { choices = names, all_choices = all_names }
  end,
  card_filter = function(self, to_select, selected)
    return Fk:currentRoom():getCardArea(to_select) == Card.PlayerHand
  end,
  view_as = function(self, cards)
    local n = Self:usedSkillTimes(self.name, Player.HistoryPhase) + 1
    if #cards ~= n or not self.interaction.data then return nil end
    local card = Fk:cloneCard(self.interaction.data)
    card:addSubcards(cards)
    card.skillName = self.name
    return card
  end,
  enabled_at_play = function(self, player)
    return not player:isKongcheng()
  end,
  enabled_at_response = function(self, player, response)
    return false
  end,
}

local qiyao_trigger = fk.CreateTriggerSkill{
  name = "#qiyao_trigger",
  mute = true,
  refresh_events = {fk.CardUsing, fk.CardUseFinished},
  can_refresh = function(self, event, target, player, data)
    return player:hasSkill(self) and target == player and data.card:isCommonTrick()
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    if event == fk.CardUsing then
      local mark = U.getMark(player, "ev__qiyao-turn")
      table.insert(mark, data.card.trueName)
      room:setPlayerMark(player, "ev__qiyao-turn", mark)
    else
      if data.card.skillName == "ev__qiyao" then
        if player:usedSkillTimes("ev__qiyao", Player.HistoryPhase) > 1 and
        #TargetGroup:getRealTargets(data.tos) > player:usedSkillTimes("ev__qiyao", Player.HistoryPhase) then
          room:loseHp(player, 1, "ev__qiyao")
        end
      end
    end
  end,
}

ev__qiyao:addRelatedSkill(qiyao_trigger)
Patchouli:addSkill(ev__qiyao)

local ev__riyin_trigger = fk.CreateTriggerSkill{
  name = "#ev__riyin_trigger",
  refresh_events = {fk.HandleAskForPlayCard, fk.PreCardEffect},
  can_refresh = function(self, event, target, player, data)
    if event == fk.PreCardEffect then
      return player:hasSkill("ev__riyin") and data.card.type == Card.TypeTrick and player.phase == Player.NotActive
    else
      return data.eventData and data.eventData.from == player.id and data.eventData.card.type == Card.TypeTrick
      and player.phase ~= Player.NotActive and player:hasSkill("ev__riyin")
    end
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    if event == fk.PreCardEffect then
      room:setPlayerMark(player, "ev__riyin_record", {data.card:getSuitString()})
    else
      if not data.afterRequest then
        room:setBanner("@ev__riyin_record", data.eventData.card:getSuitString())
      else
        room:setBanner("@ev__riyin_record", 0)
      end
    end
  end,
}

local ev__riyin = fk.CreateViewAsSkill{
  name = "ev__riyin",
  pattern = "nullification",
  card_filter = function(self, to_select, selected)
    local suit = Self:getMark("ev__riyin_record")
    if type(suit) == "table" then
      suit = suit[1]
    else
      return false
    end
    return #selected == 0 and Fk:getCardById(to_select):getSuitString() ~= suit
  end,
  view_as = function(self, cards)
    if #cards ~= 1 then
      return nil
    end
    local c = Fk:cloneCard("ev__nullification")
    c.skillName = self.name
    c:addSubcard(cards[1])
    return c
  end,
  enabled_at_play = Util.FalseFunc,
  enabled_at_response = function(self, player, response)
    return player.phase == Player.NotActive
  end,
  before_use = function(self, player)
    player.room:setPlayerMark(player, "ev__riyin_record", 0)
  end,
}

local ev__riyin_prohibit = fk.CreateProhibitSkill{
  name = "#ev__riyin_prohibit",
  prohibit_use = function(self, player, card)
    local room = Fk:currentRoom()
    local suit = room:getBanner("@ev__riyin_record")
    if suit and suit ~= 0 then
       return card and card.name == "ev__nullification" and card:getSuitString() ~= suit
    end
  end,
}

ev__riyin:addRelatedSkill(ev__riyin_trigger)
ev__riyin:addRelatedSkill(ev__riyin_prohibit)
Patchouli:addSkill(ev__riyin)

Fk:loadTranslationTable{
  ["ev__patchouli"] = "帕秋莉",
  ["designer:ev__achilles"] = "夜之礼赞",
  ["ev__qiyao"] = "七曜",
  [":ev__qiyao"] = "出牌阶段，你可将X+1张手牌当你于本回合内未使用过的即时魔法牌使用；当此牌结算结束后，若X大于1且此牌指定的目标数大于X，你失去1点体力（X为你于本阶段内发动过此技能的次数）。",
  ["#ev__qiyao"] = "你可将X+1张手牌当时魔法牌使用，X为此阶段此技能发动次数",
  ["ev__riyin"] = "日阴",
  [":ev__riyin"] = "你的回合内，你使用的魔法牌不是与之花色不同的【魔法禁令】的合法目标。你的回合外，你可将与目标魔法牌花色不同的一张牌当【魔法禁令】使用。",
  ["#ev__riyin_prohibit"] = "日阴",
}

local Saber = General(extension, "ev__saber", "ev", 4, 4, General.Female)

local ev__fengwang = fk.CreateTriggerSkill{
  name = "ev__fengwang",
  anim_type = "control",
  events = {fk.TargetSpecified},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self.name) and data.card.trueName == "slash"
    and #table.filter(player:getCardIds(Player.Hand), function(id) return Fk:getCardById(id):getMark("@@shown-inhand") == 0 end) > 0
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(data.to)
    local choice = room:askForChoice(to, {"spade", "heart", "club", "diamond"}, self.name)
    local id = EV.askForCardChosen(room, to, player, 'h', self.name)
    EV.choicelog(to, choice)
    EV.OpenCards(room, player, id, self.name, to)
    if Fk:getCardById(id):getSuitString() ~= choice and to:isAlive() then
      data.disresponsive = true
    end
  end,
}
Saber:addSkill(ev__fengwang)

local ev__shiyue_choose = fk.CreateActiveSkill{
  name = "ev__shiyue_choose",
  card_num = 0,
  min_target_num = 1,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected)
    local player = Fk:currentRoom():getPlayerById(Self:getMark("shiyue_target"))
    if to_select == Self:getMark("shiyue_target") or to_select == Self.id then return false end
    local target = Fk:currentRoom():getPlayerById(to_select)
    if #selected == 0 then
      return target:getNextAlive() == player or player:getNextAlive() == target
    else
      if table.contains(selected, player:getNextAlive().id) then
        if Fk:currentRoom():getPlayerById(selected[#selected]):getNextAlive() == target then
          return true
        end
      end
      if Fk:currentRoom():getPlayerById(selected[1]):getNextAlive() == player then
        if target:getNextAlive().id == selected[#selected] then
          return true
        end
      end
    end
  end,
  feasible = function(self, selected, selected_cards)
    if #selected > 0 then
      local player = Fk:currentRoom():getPlayerById(Self:getMark("shiyue_target"))
      local p1 = Fk:currentRoom():getPlayerById(selected[1])
      if not (p1:getNextAlive() == player or player:getNextAlive() == p1) then return false end
      if #selected == 1 then return true end
      if p1:getNextAlive() == player then
        for i = 1, #selected - 1, 1 do
          if Fk:currentRoom():getPlayerById(selected[i+1]):getNextAlive() ~= Fk:currentRoom():getPlayerById(selected[i]) then
            return false
          end
        end
        return #selected <= Self:getMark("@shiyue-turn")
      end
      if player:getNextAlive() == p1 then
        for i = 1, #selected - 1, 1 do
          if Fk:currentRoom():getPlayerById(selected[i]):getNextAlive() ~= Fk:currentRoom():getPlayerById(selected[i+1]) then
            return false
          end
        end
        return #selected <= Self:getMark("@shiyue-turn")
      end
    end
  end,
}

Fk:addSkill(ev__shiyue_choose)

local ev__shiyue = fk.CreateTriggerSkill{
  name = "ev__shiyue",
  mute = true,
  events = {fk.EventPhaseStart, fk.TargetSpecifying},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and target == player then
      if event == fk.EventPhaseStart then
        return player.phase == Player.Play or (player.phase == Player.Finish and player:getMark("@shiyue-turn") > 0)
      else
        return target == player and player:getMark("@shiyue-turn") > 0 and data.card.trueName == "slash" and #U.getUseExtraTargets(player.room, data, true, true) > 0
        and data.tos and #AimGroup:getAllTargets(data.tos) == 1
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart then
      if player.phase == Player.Play then
        return room:askForSkillInvoke(player, self.name, nil, "#ev__shiyue-invoke")
      else
        return true
      end
    else
      room:setPlayerMark(player, "shiyue_target", AimGroup:getAllTargets(data.tos)[1])
      local _, dat = room:askForUseActiveSkill(player, "ev__shiyue_choose", "#ev__shiyue-choose:::"..player:getMark("@shiyue-turn"), true)
      room:setPlayerMark(player, "shiyue_target",0)
      if dat then
        self.cost_data = dat.targets
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart then
      if player.phase == Player.Play then
        local numbers = {}
        for _, p in ipairs(room.alive_players) do
          if not p:isKongcheng() then
            for _, id in ipairs(p:getCardIds(Player.Hand)) do
              if Fk:getCardById(id):getMark("@@shown-inhand") ~= 0 then
                table.insertIfNeed(numbers, Fk:getCardById(id).number)
              end
            end
          end
        end
        if #numbers > 0 then
          player:drawCards(#numbers, self.name)
          room:setPlayerMark(player, "@shiyue-turn", #numbers)
          room:notifySkillInvoked(player, self.name, "big")
        end
        local unshown = table.filter(player:getCardIds(Player.Hand), function(id) return Fk:getCardById(id):getMark("@@shown-inhand") == 0 end)
        EV.OpenCards(room, player, unshown, self.name)
      elseif player.phase == Player.Finish then
        local n = 0
        U.getActualDamageEvents(player.room, 1, function(e)
          local damage = e.data[1]
          if damage.from == player then
            n = n + damage.damage
          end
        end)
        if n < player:getMark("@shiyue-turn") then
          room:askForDiscard(player, player:getMark("@shiyue-turn"), player:getMark("@shiyue-turn"), true, self.name, false)
        end
      end
    else
      for _, pid in ipairs(self.cost_data) do
        AimGroup:addTargets(room, data, pid)
      end
      room:sendLog{
        type = "#AddTargetsBySkill",
        from = player.id,
        to = self.cost_data,
        arg = self.name,
        arg2 = data.card:toLogString(),
        toast = true,
      }
    end
  end,
}

Saber:addSkill(ev__shiyue)

Fk:loadTranslationTable{
  ["ev__saber"] = "阿尔托莉雅",
  ["designer:ev__misaka"] = "夜之礼赞",
  ["ev__fengwang"] = "风王结界",
  [":ev__fengwang"] = "当你使用【杀】指定一个目标后，你可令其选择一种花色并明置你的一张手牌，若此牌的花色与其选择的不同，此【杀】不是【闪】的合法目标。",
  ["ev__shiyue"] = "誓约之剑",
  [":ev__shiyue"] = "出牌阶段开始时，你可摸等同于所有角色的明置手牌的点数种类的牌，然后明置所有手牌；若如此做，当你于本回合内使用【杀】指定一个目标时，可额外选择与其连续相邻的至多X名其他角色为目标。结束阶段，若你于本回合内造成过的伤害数小于X，你弃置X张牌（X为你以此法摸的牌数）。",
  ["#ev__shiyue-invoke"] = "你可以发动誓约胜利之剑",
  ["@shiyue-turn"] = "誓约胜利",
  ["#ev__shiyue-choose"] = "你可以增加目标连续相邻的至多%arg名其他角色",
}

local Eirin = General(extension, "ev__eirin", "ev", 3, 3, General.Female)

local ev__mizang = fk.CreateTriggerSkill{
  name = "ev__mizang",
  events = {fk.TurnEnd},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and player:usedSkillTimes(self.name, Player.HistoryRound) == 0 then
      return #table.filter(player.room.alive_players, function(p) return p:inMyAttackRange(target) end) >= target.hp
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local n = math.min(target.maxHp, 4) * 2
    local card_ids = room:getNCards(n, "bottom")
    local to_throw = room:askForCardsChosen(player, player, 0, n, {
      card_data = {
        { "Bottom", card_ids }
      }
    }, self.name, "#ev__mizang-throw")
    if #to_throw > 0 then
      for _, id in ipairs(to_throw) do
        table.removeOne(card_ids, id)
      end
      room:moveCards({
        ids = to_throw,
        toArea = Card.DiscardPile,
        moveReason = fk.ReasonPutIntoDiscardPile,
        skillName = self.name,
      })
    end
    if #card_ids > 0 then
      room:askForGuanxing(player, card_ids)
    end
  end,
}

local ev__susheng = fk.CreateTriggerSkill{
  name = "ev__susheng",
  anim_type = "support",
  events = {fk.EnterDying},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self.name) and (target == player or #target:getCardIds("he") > 0)
  end,
  on_cost = function(self, event, target, player, data)
    if target == player then
      return player.room:askForSkillInvoke(player, self.name)
    else
      return player.room:askForSkillInvoke(target, self.name, data, "#ev__susheng-invoke::"..player.id)
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local n = 0
    if target == player then
      player:drawCards(1, self.name, "bottom")
      n = 1
    else
      local cards = EV.askForCardsChosen(room, player, target, 1, #target:getCardIds("he"), "hes", self.name)
      room:moveCardTo(cards, Player.Hand, player, fk.ReasonPrey, self.name, nil, false, player.id)
      n = #cards
    end
    local to_throw = room:askForDiscard(player, n, 999, true, self.name, false, ".", "#ev__susheng-discard:::"..n, true)
    room:moveCardTo(to_throw, Card.DiscardPile, nil, fk.ReasonDiscard, self.name, "", true, player.id)
    if target == player then
      local colors = {}
      for _, id in ipairs(to_throw) do
        table.insertIfNeed(colors, Fk:getCardById(id).color)
      end
      if #colors == 2 then 
        room:recover({
          who = player,
          num = 1 - player.hp,
          recoverBy = player,
          skillName = self.name
        })
      end
    end
    if target ~= player and EV.countSuits(to_throw) == 4 then
      room:recover({
        who = target,
        num = target.maxHp - target.hp,
        recoverBy = player,
        skillName = self.name
      })
    end
  end,
}

Eirin:addSkill(ev__mizang)
Eirin:addSkill(ev__susheng)

Fk:loadTranslationTable{
  ["ev__eirin"] = "八意永琳",
  ["designer:ev__eirin"] = "KINGDOM43",
  ["ev__mizang"] = "<font color=\"#D2042D\">密</font><font color=\"#1F51FF\">葬</font>",
  [":ev__mizang"] = "轮次技，一名角色的回合结束时，若攻击范围内含有其的角色数不小于其体力值，你可观看牌堆底的2X张牌，将其中的任意张牌置入弃牌堆，然后你将其中的任意张牌置于牌堆顶（X为其体力上限且至多为4）。",
  ["#ev__mizang-throw"] = "请选择任意张牌置入弃牌堆",
  ["ev__susheng"] = "<font color=\"#D2042D\">苏</font><font color=\"#1F51FF\">生</font>",
  [":ev__susheng"] = "当一名角色进入濒死状态时，若其：<font color=\"#D2042D\">为你</font>/<font color=\"#1F51FF\">不为你</font>，"..
  "<font color=\"#D2042D\">你可从牌堆底摸一张牌</font>/<font color=\"#1F51FF\">其可令你选择其任意张牌并获得之</font>，"..
  "然后你弃置至少等量张牌，若其中含有所有<font color=\"#D2042D\">颜色</font>/<font color=\"#1F51FF\">花色</font>，"..
  "<font color=\"#D2042D\">你</font>/<font color=\"#1F51FF\">其</font>将体力回复至<font color=\"#D2042D\">1点</font>/<font color=\"#1F51FF\">体力上限</font>。",
  ["#ev__susheng-invoke"] = "你可以令%dest选择你任意张牌获得之",
  ["#ev__susheng-discard"] = "请弃置至少%arg张牌",
}

local heiyansheshou = General(extension, "ev__heiyansheshou", "ev", 4, 4, General.Female)

local ev__jueduiyazhi = fk.CreateTriggerSkill{
  name = "ev__jueduiyazhi",
  anim_type = "offensive",
  events = {fk.TargetSpecified, fk.TurnEnd},
  can_trigger = function(self, event, target, player, data)
    if event == fk.TargetSpecified then
      return target == player and player:hasSkill(self) and data.card.trueName == "slash" and not player.room:getPlayerById(data.to):isNude()
    else
      return player:hasSkill(self.name, true, true) and
       #table.filter(player.room.alive_players, function(p) return p:getMark("jueduiyazhi-turn") > 0 end) > 0
    end
  end,
  on_cost = function(self, event, target, player, data)
    if event == fk.TargetSpecified then
      return player.room:askForSkillInvoke(player, self.name)
    else
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TargetSpecified then
      local to = room:getPlayerById(data.to)
      --local cards = room:askForCardsChosen(player, to, 0, to.hp, "he", self.name)
      local cards = EV.askForCardsChosen(room, player, to, 0, to.hp, "hes", self.name)
      if #cards > 0 then
        room:addPlayerMark(to, "jueduiyazhi-turn", #cards)
        room:moveCardTo(cards, Card.DiscardPile, nil, fk.ReasonDiscard, self.name, "", true, player.id)
      end
    else
      for _, p in ipairs(room:getAlivePlayers()) do
        if p:getMark("jueduiyazhi-turn") > 0 then
          p:drawCards(p:getMark("jueduiyazhi-turn"), self.name)
          room:setPlayerMark(p, "jueduiyazhi-turn", 0)
        end
      end
    end
  end,
}

local gattlingmode_attackrange = fk.CreateAttackRangeSkill{
  name = "#gattlingmode_attackrange",
  correct_func = function (self, from, to)
    if from:hasSkill("ev__gattlingmode") then
      return #from:getCardIds(Player.Equip)
    end
  end,
}

local ev__gattlingmode = fk.CreateTriggerSkill{
  name = "ev__gattlingmode",
  events = {fk.Damage},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.card and data.card.trueName == "slash" and not data.to.dead
  end,
  on_cost = function(self, event, target, player, data)
    local card = player.room:askForCard(player, 1, 1, true, self.name, true, ".|.|spade", "#ev__gattlingmode::"..data.to.id)
    if #card > 0 then
      self.cost_data = card
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    player.room:useVirtualCard("ev__slash", self.cost_data, player, data.to, self.name, false)
  end,
}

ev__gattlingmode:addRelatedSkill(gattlingmode_attackrange)
heiyansheshou:addSkill(ev__jueduiyazhi)
heiyansheshou:addSkill(ev__gattlingmode)

Fk:loadTranslationTable{
  ["ev__heiyansheshou"] = "黑岩射手",
  ["designer:ev__heiyansheshou"] = "小樱",
  ["ev__jueduiyazhi"] = "绝对压制",
  [":ev__jueduiyazhi"] = "当你使用【杀】指定一个目标后，你可弃置其至多等同于其体力值张牌；若如此做，其于当前回合结束时摸等量张牌。",
  ["ev__gattlingmode"] = "机枪模式",
  [":ev__gattlingmode"] = "你的攻击范围+X（X为你装备区里的牌数）。当你使用【杀】对目标角色造成伤害后，你可将一张黑桃牌当【杀】对其使用。",
  ["#ev__gattlingmode"] = "你可将一张黑桃牌当【杀】对%dest使用",
}

local Misaka = General(extension, "ev__misaka", "ev", 4, 4, General.Female)

local electrans = fk.CreateTriggerSkill{
  name = "electrans",
  events = {fk.Damaged, fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    if event == fk.Damaged then 
      return player:hasSkill(self) and #data.to:getCardIds(Player.Equip) > 0 and data.damageType == fk.ThunderDamage
    else
      return player:hasSkill(self) and target == player and player.phase == Player.Start
      and #table.filter(player:getCardIds("he"),function(id) return Fk:getCardById(id).type == Card.TypeEquip end) > 0
      and #table.filter(player.room.discard_pile,function(id) return Fk:getCardById(id).type == Card.TypeEquip end) > 0
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.Damaged then 
      local id = room:askForCardChosen(player, data.to, "e", self.name)
      if id > 0 then
        room:moveCardTo(id, Card.DiscardPile, nil, fk.ReasonDiscard, self.name, "", true, player.id)
      end
    else
      local equips = table.filter(player:getCardIds("he"),function(id) return Fk:getCardById(id).type == Card.TypeEquip end)
      local cards = table.filter(player.room.discard_pile,function(id) return Fk:getCardById(id).type == Card.TypeEquip end)
      --[[local cids = room:askForArrangeCards(player, self.name,
      {cards, equips, self.name, player.general}, "#electrans-exchange", true)
      U.swapCardsWithPile(player, cids[1], cids[2], self.name, "discardPile", true, player.id)]]
      local cids = U.askForExchange(player, self.name, player.general, cards, equips, "#electrans-exchange", 1, true)
      if #cids > 0 then
        equips = table.filter(cids, function (id)
          return table.contains(player:getCardIds("he"), id)
        end)
        cards = table.filter(cids, function (id)
          return not table.contains(player:getCardIds("he"), id)
        end)
        U.swapCardsWithPile(player, equips, cards, self.name, "discardPile", true, player.id)
      end
    end
  end,
}

local Railgun = fk.CreateViewAsSkill{
  name = "railgun",
  anim_type = "offensive",
  pattern = "ev__slash",
  card_filter = function(self, to_select, selected)
    return #selected == 0 and Fk:getCardById(to_select).suit == Card.Spade or Fk:getCardById(to_select).type == Card.TypeEquip
  end,
  view_as = function(self, cards)
    if #cards ~= 1 then return end
    local pattern = "ev_thunder__slash"
    if Fk:getCardById(cards[1]).suit == Card.Spade and Fk:getCardById(cards[1]).type == Card.TypeEquip then
      pattern = "super_thunder__slash"
    end
    local card = Fk:cloneCard(pattern)
    card.skillName = self.name
    card:addSubcard(cards[1])
    return card
  end,
}
Misaka:addSkill(electrans)
Misaka:addSkill(Railgun)

Fk:loadTranslationTable{
  ["ev__misaka"] = "御坂美琴",
  ["designer:ev__misaka"] = "zengyouyu",
  ["super_thunder__slash"] = "雷杀",
  [":super_thunder__slash"] = "御坂美琴专用雷杀，可指定连续相邻的至少两名其他角色",
  ["electrans"] = "电磁转换",
  [":electrans"] = "当一名角色受到雷电伤害时，你可弃置其装备区里的一张牌。准备阶段，你可用一张装备牌替换弃牌堆里的一张装备牌。",
  ["#electrans-exchange"] = "你可用一张装备牌替换弃牌堆里的一张装备牌",
  ["railgun"] = "超电磁炮",
  [":railgun"] = "你可将一张黑桃牌或装备牌当雷【杀】使用或打出；若此牌为黑桃装备牌，此雷【杀】的“使用目标”后增加“或连续相邻的至少两名其他角色”。",
}

local selina = General(extension, "ev__selina", "ev", 3, 3, General.Female)

local ev__juezhi = fk.CreateTriggerSkill{
  name = "ev__juezhi",
  mute = true,
  events = {fk.EventPhaseStart, fk.EventPhaseEnd, fk.CardUsing},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      if event == fk.EventPhaseStart then
        return target.phase == Player.Play and not player:isKongcheng()
      elseif event == fk.EventPhaseEnd then
        return target.phase == Player.Play and target:getMark("juezhi-phase") > 0
      else
        return data.card:getMark("juezhi-use") > 0
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    if event == fk.EventPhaseStart then
      local unshown = table.filter(player:getCardIds(Player.Hand), function(id) return Fk:getCardById(id):getMark("@@shown-inhand") == 0 end)
      local cards = player.room:askForCard(player, player.hp, player.hp, true, self.name, true,
      ".|.|.|.|.|.|" .. table.concat(unshown, ","), "#ev__juezhi-show:::"..player.hp)
      if #cards > 0 then
        self.cost_data = cards
        return true
      end
    else
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.EventPhaseStart then
      room:addPlayerMark(player, "juezhi-phase")
      room:notifySkillInvoked(player, self.name, "special")
      EV.OpenCards(room, player, self.cost_data, self.name)
    elseif event == fk.EventPhaseEnd then
      local shown = table.filter(player:getCardIds(Player.Hand), function(id) return Fk:getCardById(id):getMark("@@shown-inhand") > 0 end)
      if #shown > 0 then
        room:moveCardTo(shown, Card.DiscardPile, nil, fk.ReasonDiscard, self.name, "", true, player.id)
      else
        room:addPlayerMark(player, "AddMaxCards-turn", 1)
      end
    else
      room:notifySkillInvoked(player, self.name, "drawcard")
      player:drawCards(1, self.name)
    end
  end,
  refresh_events = {fk.PreCardUse},
  can_refresh = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.card:getMark("@@shown-inhand") > 0
  end,
  on_refresh = function(self, event, target, player, data)
    local typesRecorded = U.getMark(player, "@[cardtypes]juezhi-turn")
    if not table.contains(typesRecorded, data.card.type) then
      table.insert(typesRecorded, data.card.type)
      player.room:setCardMark(data.card, "juezhi-use", 1)
    end
    player.room:setPlayerMark(player, "@[cardtypes]juezhi-turn", typesRecorded)
  end 
}

local ev__jieyi = fk.CreateTriggerSkill{
  name = "ev__jieyi",
  anim_type = "drawcard",
  events = {fk.EventPhaseEnd},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and target.phase == Player.Discard then
      local room = player.room
      local turn_event = room.logic:getCurrentEvent():findParent(GameEvent.Turn, true)
      local end_id = turn_event.id
      local ids = {}
      U.getEventsByRule(room, GameEvent.MoveCards, 999, function (e)
        for _, move in ipairs(e.data) do
          if move.from and move.from == target.id and move.moveReason == fk.ReasonDiscard then
            for _, info in ipairs(move.moveInfo) do
              if info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip then
                table.insert(ids, info.cardId)
              end
            end
          end
        end
        return false
      end, end_id)
      return #ids >= target.hp
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    target:drawCards(1, self.name)
    U.askForPlayCard(room, target, target:getHandlyIds(true), ".", self.name)
  end,
}

selina:addSkill(ev__juezhi)
selina:addSkill(ev__jieyi)

Fk:loadTranslationTable{
  ["ev__selina"] = "莎莉娜",
  ["designer:ev__selina"] = "潜水员最棒",
  ["ev__juezhi"] = "决志",
  [":ev__juezhi"] = "出牌阶段开始时，你可明置X张手牌，则本阶段结束时，若你没有/有明置手牌，则你的手牌上限于本回合内+1/你弃置所有明置手牌（X为你的体力值）。当你于当前回合内首次使用一种类别的明置手牌时，你摸一张牌。",
  ["#ev__juezhi-show"] = "决志：你可明置%arg张手牌",
  ["@[cardtypes]juezhi-turn"] = "决志",
  ["ev__jieyi"] = "解意",
  [":ev__jieyi"] = "一名角色的弃牌阶段结束时，若其于本回合内弃置的牌数不小于体力值，你可令其摸一张牌，然后其可使用一张牌。",
}

local yunru = General(extension, "ev__yunru", "ev", 3, 3, General.Female)

local ev__rouzhi = fk.CreateTriggerSkill{
  name = "ev__rouzhi",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target ~= player and player:hasSkill(self) and target:inMyAttackRange(player) and target.phase == Player.Play
  end,
  on_cost = function(self, event, target, player, data)
    local card = player.room:askForCard(player, 1, 1, true, self.name, true, ".", "#ev__rouzhi::"..target.id)
    if #card > 0 then
      self.cost_data = card[1]
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local color = Fk:getCardById(self.cost_data):getColorString()
    player.room:moveCardTo(self.cost_data, Card.DiscardPile, nil, fk.ReasonDiscard, self.name, nil, true, player.id)
    local mark = U.getMark(target, "ev__rouzhi-turn")
    table.insertIfNeed(mark, color)
    player.room:setPlayerMark(target, "ev__rouzhi-turn", mark)
  end,
}

local rouzhi_prohibit = fk.CreateProhibitSkill{
  name = "#ev__rouzhi_prohibit",
  prohibit_use = function(self, player, card)
    if player:getMark("ev__rouzhi-turn") ~= 0 and card then
      return table.contains(U.getMark(player, "ev__rouzhi-turn"), card:getColorString())
    end
  end,
  prohibit_response = function(self, player, card)
    if player:getMark("ev__rouzhi-turn") ~= 0 and card then
      return table.contains(U.getMark(player, "ev__rouzhi-turn"), card:getColorString())
    end
  end,
}

local ev__jingzhen = fk.CreateTriggerSkill{
  name = "ev__jingzhen",
  events = {fk.TurnEnd},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      local turn_event = player.room.logic:getCurrentEvent():findParent(GameEvent.Turn, true)
      local end_id = turn_event.id
      return #U.getEventsByRule(player.room, GameEvent.MoveCards, 1, function (e)
        for _, move in ipairs(e.data) do
          if move.from and move.from == player.id and (move.to == nil or move.to ~= player.id) then
            for _, info in ipairs(move.moveInfo) do
              if Fk:getCardById(info.cardId).type == Card.TypeEquip and (info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip) then
                return true
              end
            end
          end
        end
        return false
      end, end_id) > 0
    end
  end,
  on_cost = function(self, event, target, player, data)
    local tos = player.room:askForChoosePlayers(player, table.map(player.room.alive_players, Util.IdMapper), 1, 99, "#ev__jingzhen-choose", self.name, true)
    if #tos > 0 then
      self.cost_data = tos
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    for _, p in ipairs(self.cost_data) do
      local to = room:getPlayerById(p)
      if #to:getCardIds(Player.Equip) > 0 and not to.dead then
        local card = room:askForCard(to, 1, 1, true, self.name, false, ".|.|.|equip", "#ev__jingzhen")
        room:moveCardTo(card, Card.PlayerHand, to, fk.ReasonJustMove, self.name, "", true, p)
      end
    end
    for _, p in ipairs(self.cost_data) do
      local to = room:getPlayerById(p)
      if not to.dead and not to:isKongcheng() then
        local id = EV.askForCardChosen(room, player, to, "hs", self.name)
        room:moveCardTo(id, Card.DiscardPile, nil, fk.ReasonDiscard, self.name, "", true, player.id)
      end
    end
  end,
}

ev__rouzhi:addRelatedSkill(rouzhi_prohibit)
yunru:addSkill(ev__rouzhi)
yunru:addSkill(ev__jingzhen)

Fk:loadTranslationTable{
  ["ev__yunru"] = "云茹",
  ["designer:ev__yunru"] = "子规枝上",
  ["ev__rouzhi"] = "柔制",
  [":ev__rouzhi"] = "其他角色的出牌阶段开始时，若其攻击范围内含有你，你可弃置一张牌，令其于此回合内不能使用或打出与之颜色相同的牌。",
  ["#ev__rouzhi"] = "柔制：你可弃置一张牌，令%dest于此回合内不能使用或打出与之颜色相同的牌",
  ["#ev__rouzhi_prohibit"] = "柔制",
  ["ev__jingzhen"] = "惊震",
  [":ev__jingzhen"] = "回合技（终），若你于此回合内失去过装备牌，你可选择任意名角色，令这些角色各获得其自己装备区里的一张牌，然后你弃置这些角色的各一张手牌。",
  ["#ev__jingzhen-choose"] = "惊震：你可选择任意名角色",
  ["#ev__jingzhen"] = "惊震：请选择装备区里的一张牌获得",
}

return extension
